package com.quick.develop.flowable.framework.cmd;

import com.quick.develop.flowable.constant.BpmConstants;
import com.quick.develop.flowable.domain.vo.task.CcToVo;
import com.quick.develop.framework.utils.StringUtils;
import org.flowable.common.engine.api.FlowableIllegalArgumentException;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.flowable.common.engine.impl.interceptor.Command;
import org.flowable.common.engine.impl.interceptor.CommandContext;
import org.flowable.engine.impl.persistence.entity.CommentEntity;
import org.flowable.engine.impl.persistence.entity.CommentEntityManager;
import org.flowable.engine.impl.persistence.entity.ExecutionEntity;
import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager;
import org.flowable.engine.impl.util.CommandContextUtil;
import org.flowable.engine.impl.util.IdentityLinkUtil;

import java.io.Serializable;
import java.util.Objects;

/**
 * @author junyuan.liu
 * @description: 
 * @date 2022/6/23 16:42
 */
public class AddCcIdentityLinkCmd implements Command<Void>, Serializable {
    private static final long serialVersionUID = 3916693344414296565L;
    protected String processInstanceId;
    protected String taskId;
    protected String userId;
    protected CcToVo[] ccToVos;

    public AddCcIdentityLinkCmd(String processInstanceId, String taskId, String userId, CcToVo[] ccToVos) {
        validateParams(processInstanceId, taskId, userId, ccToVos);
        this.processInstanceId = processInstanceId;
        this.taskId = taskId;
        this.userId = userId;
        this.ccToVos = ccToVos;
    }
    protected void validateParams(String processInstanceId, String taskId, String userId, CcToVo[] ccTo) {
        if (StringUtils.isEmpty(processInstanceId)) {
            throw new FlowableIllegalArgumentException("processInstanceId is null or empty");
        }
        if (StringUtils.isEmpty(taskId) ) {
            throw new FlowableIllegalArgumentException("taskId is null or empty");
        }
        if (StringUtils.isEmpty(userId)) {
            throw new FlowableIllegalArgumentException("userId is null or empty");
        }
        if (Objects.isNull(ccTo) || ccTo.length == 0) {
            throw new FlowableIllegalArgumentException("ccTo is null or empty");
        }
    }

    @Override
    public Void execute(CommandContext commandContext) {
        ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext);
        ExecutionEntity processInstance = executionEntityManager.findById(processInstanceId);
        if (processInstance == null) {
            throw new FlowableObjectNotFoundException("Cannot find process instance with id " + processInstanceId,
                    ExecutionEntity.class);
        }
        for (CcToVo ccTo : ccToVos) {
            IdentityLinkUtil.createProcessInstanceIdentityLink(processInstance, ccTo.getUserId(), null, BpmConstants.CC);
        }
        this.createCcComment(commandContext);
        return null;
    }

    protected void createCcComment(CommandContext commandContext) {
        CommentEntityManager commentEntityManager = CommandContextUtil.getCommentEntityManager(commandContext);
        CommentEntity comment = (CommentEntity) commentEntityManager.create();
        comment.setProcessInstanceId(processInstanceId);
        comment.setUserId(userId);
        comment.setType(BpmConstants.CC);
        comment.setTime(CommandContextUtil.getProcessEngineConfiguration(commandContext).getClock().getCurrentTime());
        comment.setTaskId(taskId);
        comment.setAction(BpmConstants.ADD_CC_TO);
        String ccToStr = org.springframework.util.StringUtils.arrayToCommaDelimitedString((Object [])ccToVos);
        String eventMessage = ccToStr.replaceAll("\\s+", " ");
        if (eventMessage.length() > 163) {
            eventMessage = eventMessage.substring(0, 160) + "...";
        }
        comment.setMessage(eventMessage);
        comment.setFullMessage(ccToStr);
        commentEntityManager.insert(comment);
    }
}
